<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            margin: 0px !important;
        }

        .list {
            height: 200vh;
            background: #0088dd;
            /* position: absolute; */
        }
    </style>
</head>

<body>
    <div class="list"></div>
    <input placeholder="输入内容" id="search" />
    <script>
        //时间戳方式实现节流, 会立即执行，但是最后一次不会立即执行
        function throttle1(fn, delay) {
            let startTime = Date.now();

            return function () {
                //执行上下文的this对象
                let context = this;
                //参数对象信息是什么
                let args = arguments;

                //当前时间对象
                let curTime = Date.now();

                //判断如果时间差超过延迟时间对象，执行函数，把开始时间还原
                if (curTime - startTime >= delay) {
                    fn.apply(context, args);
                    startTime = Date.now();
                }
            }
        }

        //采用定时器的方式，第一次不会立马执行，最后一次执行完以后在执行一次
        function throttle2(fn, delay) {
            let timeout = null;

            return function () {
                let context = this;
                let args = arguments;

                //如果当前事件不存在的话，继续执行代码
                if (!timeout) {
                    timeout = setTimeout(() => {
                        fn.apply(context, args);
                        timeout = null;
                    }, delay)
                }
            }
        }

        //结合两种写法去执行代码，取两种方法好的地方执行。
        function throttle3(fn, delay) {
            //开始的对象信息
            let timeout = null;
            let startTime = Date.now();

            return function () {
                let context = this;
                let args = arguments;

                //当前事件
                let curTime = Date.now();
                let reminding = delay - (curTime - startTime);

                if(timeout) clearTimeout(timeout);

                //如果已经到期的话，立即执行，然后再还原一下状态
                if (reminding <= 0) {
                    console.log(123)
                    fn.apply(context,args)
                    startTime = Date.now();
                }else{//如果未到期的话
                    console.log(456)
                    timeout = setTimeout(()=>{
                        fn.apply(context,args);
                        timeout = null;
                    },reminding)
                }

            }
        }

        window.addEventListener("scroll", throttle3(() => {
            console.log("页面滚动", Date.now())
        }, 1500))

    </script>
</body>

</html>